package com.veeder.datacollection.rs232;

import java.util.logging.Level;

import com.veeder.datacollection.collector.ATGFetcher;
import com.veeder.datacollection.config.ConnectionParam;
import com.veeder.datacollection.config.ConnectionParam.ConnectionMode;
import com.veeder.datacollection.exception.SyntaxException;
import com.veeder.datacollection.rs232.response.*;
import com.veeder.datacollection.rs232.response.handler.RspHandlerFactory;
import com.veeder.datacollection.rs232.response.handler.RspParser;
import com.veeder.datacollection.util.DataUtil;

public class VRTLS extends ATGFetcher {
	
	private String latestInventory=RS232CommandExecutor.getInstance().executeCommand("i201" + String.format("%02d", 0), false);

	@Override
	@SuppressWarnings("unchecked")
	public TankResponseReport<BasicTankInventory> getAllTankInventories() {
		TankResponseReport<BasicTankInventory> result = null;
		String rawResponse = RS232CommandExecutor.getInstance().executeCommand("i201" + String.format("%02d", 0), false);
		setLatestInventory(rawResponse);
		RS232Response response=parseResponse(rawResponse);
		if (response instanceof TankResponseReport) {
			result = (TankResponseReport<BasicTankInventory>) response;
		}
		return result;
	}

	@Override
	@SuppressWarnings("unchecked")
	public Boolean getTankConfigFromATG(int tankId) {
		Boolean result = null;
		RS232Response response = getParsedResponse("i601" + String.format("%02d", tankId), false);
		if (response instanceof TankResponseReport) {
			result = ((TankResponseReport<Boolean>) response).getResponse(tankId);
		}
		return result;
	}

	@Override
	@SuppressWarnings("unchecked")
	public Float getTankProbeOffsetFromATG(int tankId) {
		Float result = null;
		RS232Response response = getParsedResponse("i60F" + String.format("%02d", tankId), false);
		if (response instanceof TankResponseReport) {
			result = ((TankResponseReport<Float>) response).getResponse(tankId);
		}
		return result;
	}

	@Override
	@SuppressWarnings("unchecked")
	public Float getTankDiameterFromATG(int tankId) {
		Float result = null;
		RS232Response response = getParsedResponse("i607" + String.format("%02d", tankId), false);
		if (response instanceof TankResponseReport) {
			result = ((TankResponseReport<Float>) response).getResponse(tankId);
		}
		return result;
	}
	
	@SuppressWarnings("unchecked")
	public Float[] getTank20PointsVolumesFromATG(int tankId) {
		Float[] result = null;
		RS232Response response = getParsedResponse("i606" + String.format("%02d", tankId),false);
		if (response instanceof TankResponseReport) {
			result = ((TankResponseReport<Float[]>) response).getResponse(tankId);
		}
		return result;
	}

	@Override
	@SuppressWarnings("unchecked")
	public Float getTankCapacityFromATG(int tankId) {
		Float result = null;
		RS232Response response = getParsedResponse("i60A" + String.format("%02d", tankId), false);
		if (response instanceof TankResponseReport) {
			result = ((TankResponseReport<Float>) response).getResponse(tankId);
		}
		return result;
	}

	@Override
	@SuppressWarnings("unchecked")
	public Float getTankCoefficientFromATG(int tankId) {
		Float result = null;
		RS232Response response = getParsedResponse("i609" + String.format("%02d", tankId), false);
		if (response instanceof TankResponseReport) {
			result = ((TankResponseReport<Float>) response).getResponse(tankId);
		}
		return result;
	}

	@Override
	@SuppressWarnings("unchecked")
	public Float getTankTiltFromATG(int tankId) {
		Float result = null;
		RS232Response response = getParsedResponse("i608" + String.format("%02d", tankId), false);
		if (response instanceof TankResponseReport) {
			result = ((TankResponseReport<Float>) response).getResponse(tankId);
		}
		return result;
	}

	@Override
	@SuppressWarnings("unchecked")
	public Float getTankProbeFloatSizeFromATG(int tankId) {
		MagProbeFloatSize result = null;
		RS232Response response = getParsedResponse("i62F" + String.format("%02d", tankId), false);
		if (response instanceof TankResponseReport) {
			result = ((TankResponseReport<MagProbeFloatSize>) response).getResponse(tankId);
		}
		return MagProbeFloatSize.getFloatSize(result);
	}

	@Override
	@SuppressWarnings("unchecked")
	public TankChart getTankChartFromATG(int tankId) {
		TankChart result = null;
		String command = "i211" + String.format("%02d", tankId) + DataUtil.floatToHex(30.0f);
		RS232Response response = getParsedResponse(command, false);
		if (response instanceof TankResponseReport) {
			result = ((TankResponseReport<TankChart>) response).getResponse(tankId);
		}
		return result;
	}

	@Override
	public AlarmList getActiveAlarmListFromATG() {
		AlarmList activeAlarms = null;
		RS232Response response = getParsedResponse("i11300", false);
		if (response instanceof AlarmList) {
			activeAlarms = (AlarmList) response;
		}
		return activeAlarms;
	}

	@Override
	@SuppressWarnings("unchecked")
	public String getTankProductNoFromATG(int tankId) {
		String result = null;
		RS232Response response = getParsedResponse("i602" + String.format("%02d", tankId), false);
		if (response instanceof TankResponseReport) {
			result = ((TankResponseReport<String>) response).getResponse(tankId);
		}
		return result;
	}

	public final RS232Response getParsedResponse(String command, boolean closeAfterReading) {
		String rawResponse = RS232CommandExecutor.getInstance().executeCommand(command, closeAfterReading&&ConnectionMode.SerialCommunication.equals(getConnectionParam().getMode()));
		return parseResponse(rawResponse);
	}
	
	public final RS232Response parseResponse(String rawResponse) {
		RS232Response result = null;
		if (rawResponse != null && rawResponse.length() > 5) {
			String funCode = rawResponse.substring(1, 5);
			try {
				RspParser parser = RspHandlerFactory.getResponseHandler(funCode);
				if (parser != null) {
					result = parser.parseResponse(rawResponse);
				}
			} catch (SyntaxException e) {
				logger.log(Level.WARNING, "parse message error, response : " + rawResponse);
			}
		}

		return result;
	}

	@Override
	public ConnectionParam getConnectionParam() {
		return RS232CommandExecutor.getConnectionParam();
	}

	@Override
	public String getLatestInventory() {
		return latestInventory;
	}
	
	private void setLatestInventory(String rawMessage){
		this.latestInventory=rawMessage;
	}
	
	public String setTankDiameter(int tankId, float diameter){
		return RS232CommandExecutor.getInstance().executeCommand("s607" + String.format("%02d", tankId)+DataUtil.floatToHex(diameter), false);
	}
	
	public String setTank20PointsChart(int tankId, float[] chart){
		StringBuilder builder= new StringBuilder();
		builder.append("s606" + String.format("%02d", tankId));
		for(int i=0;i<chart.length;i++){
			builder.append(DataUtil.floatToHex(chart[i]));
		}
		return RS232CommandExecutor.getInstance().executeCommand(builder.toString(), false);
	}
	
	
}
